.\" This file is dual-licensed.  Choose whichever you want.
.\"
.\" The first licence is a regular 2-clause BSD licence.  The second licence
.\" is the CC-0 from Creative Commons. It is intended to release Monocypher
.\" to the public domain.  The BSD licence serves as a fallback option.
.\"
.\" SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
.\"
.\" ----------------------------------------------------------------------------
.\"
.\" Copyright (c) 2017-2019 Loup Vaillant
.\" Copyright (c) 2018 Michael Savage
.\" Copyright (c) 2017, 2019-2020 Fabio Scotoni
.\" All rights reserved.
.\"
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions are
.\" met:
.\"
.\" 1. Redistributions of source code must retain the above copyright
.\"    notice, this list of conditions and the following disclaimer.
.\"
.\" 2. Redistributions in binary form must reproduce the above copyright
.\"    notice, this list of conditions and the following disclaimer in the
.\"    documentation and/or other materials provided with the
.\"    distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
.\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
.\" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
.\" HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
.\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" ----------------------------------------------------------------------------
.\"
.\" Written in 2017-2020 by Loup Vaillant, Michael Savage and Fabio Scotoni
.\"
.\" To the extent possible under law, the author(s) have dedicated all copyright
.\" and related neighboring rights to this software to the public domain
.\" worldwide.  This software is distributed without any warranty.
.\"
.\" You should have received a copy of the CC0 Public Domain Dedication along
.\" with this software.  If not, see
.\" <https://creativecommons.org/publicdomain/zero/1.0/>
.\"
.Dd March 31, 2020
.Dt INTRO 3MONOCYPHER
.Os
.Sh NAME
.Nm intro
.Nd introduction to Monocypher
.Sh DESCRIPTION
Monocypher is a cryptographic library.
It provides functions for authenticated encryption, hashing, password
hashing and key derivation, key exchange, and public key signatures.
.Ss Authenticated encryption
.Xr crypto_lock 3monocypher
and
.Xr crypto_unlock 3monocypher
use the Chacha20 cipher and the Poly1305 one-time authenticator.
.Pp
Chacha20 is a stream cipher based on a cryptographic hash function.
It runs efficiently on a wide variety of hardware, and unlike AES
naturally runs in constant time on all hardware.
.Pp
Poly1305 is a one-time authenticator, derived from Carter & Wegman
universal hashing.
It is very fast and very simple.
.Pp
For specialised needs,
.Xr crypto_chacha20 3monocypher
and
.Xr crypto_poly1305 3monocypher
are available to implement constructions involving them.
Whenever possible,
.Xr crypto_lock 3monocypher
should be preferred, however.
.Ss Hashing
.Xr crypto_blake2b 3monocypher
implements the Blake2b hash.
Blake2b combines the security of SHA-3 and the speed of MD5.
It is immune to length extension attacks and provides a keyed mode
that makes it a safe, easy to use authenticator.
.Ss Password hashing and key derivation
.Xr crypto_argon2i 3monocypher
implements the Argon2i resource intensive hash algorithm,
which can be used to hash passwords for storage and to derive keys
from passwords.
Argon2 won the password hashing competition in 2015.
Unlike Scrypt, Argon2i is immune to timing attacks.
.Ss Key exchange
.Xr crypto_key_exchange 3monocypher
implements X25519, an elliptic curve Diffie Hellman key exchange
algorithm based on Curve25519.
X25519 derives a shared secret from two private/public key pairs.
It is fast, simple, and relatively easy to implement securely.
.Pp
For specialised protocols that require indistinguishability from random
noise,
.Xr crypto_curve_to_hidden 3monocypher
gives the option to disguise ephemeral (one-time use) X25519 public keys
as random noise.
.Ss Public key signatures
.Xr crypto_sign 3monocypher
and
.Xr crypto_check 3monocypher
implement EdDSA, with Curve25519 and Blake2b.
This is the same as the more famous Ed25519, with SHA-512 replaced by
the faster and more secure Blake2b.
.Pp
For highly specialised needs,
it is possible to use a custom hash function with EdDSA;
see
.Xr crypto_sign_init_first_pass_custom_hash 3monocypher .
.Ss Constant time comparison
.Xr crypto_verify16 3monocypher ,
.Xr crypto_verify32 3monocypher ,
and
.Xr crypto_verify64 3monocypher
compare buffers in constant time.
They should be used to compare secrets to prevent timing attacks.
.Ss Memory wipe
.Xr crypto_wipe 3monocypher
wipes a buffer.
It is meant to erase secrets when they are no longer needed, to reduce
the chances of leaks.
.Ss Optional code
If Monocypher was compiled and installed with
.Dv USE_ED25519 ,
SHA-512 functions become available as well.
See
.Xr crypto_ed25519_sign 3monocypher ,
.Xr crypto_ed25519_sign_init_first_pass 3monocypher ,
.Xr crypto_sha512 3monocypher ,
and
.Xr crypto_hmac_sha512 3monocypher .
.Sh SEE ALSO
.Xr crypto_argon2i 3monocypher ,
.Xr crypto_argon2i_general 3monocypher ,
.Xr crypto_blake2b 3monocypher ,
.Xr crypto_blake2b_final 3monocypher ,
.Xr crypto_blake2b_general 3monocypher ,
.Xr crypto_blake2b_general_init 3monocypher ,
.Xr crypto_blake2b_init 3monocypher ,
.Xr crypto_blake2b_update 3monocypher ,
.Xr crypto_chacha20 3monocypher ,
.Xr crypto_chacha20_ctr 3monocypher ,
.Xr crypto_check 3monocypher ,
.Xr crypto_check_final 3monocypher ,
.Xr crypto_check_init 3monocypher ,
.Xr crypto_check_init_custom_hash 3monocypher ,
.Xr crypto_check_update 3monocypher ,
.Xr crypto_curve_to_hidden 3monocypher ,
.Xr crypto_from_eddsa_private 3monocypher ,
.Xr crypto_from_eddsa_public 3monocypher ,
.Xr crypto_hchacha20 3monocypher ,
.Xr crypto_hidden_key_pair 3monocypher ,
.Xr crypto_hidden_to_curve 3monocypher ,
.Xr crypto_ietf_chacha20 3monocypher ,
.Xr crypto_ietf_chacha20_ctr 3monocypher ,
.Xr crypto_key_exchange 3monocypher ,
.Xr crypto_lock 3monocypher ,
.Xr crypto_lock_aead 3monocypher ,
.Xr crypto_poly1305 3monocypher ,
.Xr crypto_poly1305_final 3monocypher ,
.Xr crypto_poly1305_init 3monocypher ,
.Xr crypto_poly1305_update 3monocypher ,
.Xr crypto_sign 3monocypher ,
.Xr crypto_sign_final 3monocypher ,
.Xr crypto_sign_init_first_pass 3monocypher ,
.Xr crypto_sign_init_first_pass_custom_hash 3monocypher ,
.Xr crypto_sign_init_second_pass 3monocypher ,
.Xr crypto_sign_public_key 3monocypher ,
.Xr crypto_sign_public_key_custom_hash 3monocypher ,
.Xr crypto_sign_update 3monocypher ,
.Xr crypto_unlock 3monocypher ,
.Xr crypto_unlock_aead 3monocypher ,
.Xr crypto_verify16 3monocypher ,
.Xr crypto_verify32 3monocypher ,
.Xr crypto_verify64 3monocypher ,
.Xr crypto_wipe 3monocypher ,
.Xr crypto_x25519 3monocypher ,
.Xr crypto_x25519_dirty_fast 3monocypher ,
.Xr crypto_x25519_dirty_small 3monocypher ,
.Xr crypto_x25519_inverse 3monocypher ,
.Xr crypto_x25519_public_key 3monocypher ,
.Xr crypto_xchacha20 3monocypher ,
.Xr crypto_xchacha20_ctr 3monocypher
.Ss Optional code
.Xr crypto_from_ed25519_private 3monocypher ,
.Xr crypto_from_ed25519_public 3monocypher ,
.Xr crypto_ed25519_check 3monocypher ,
.Xr crypto_ed25519_check_init 3monocypher ,
.Xr crypto_ed25519_check_update 3monocypher ,
.Xr crypto_ed25519_check_final 3monocypher ,
.Xr crypto_ed25519_public_key 3monocypher ,
.Xr crypto_ed25519_sign 3monocypher ,
.Xr crypto_ed25519_sign_init_first_pass 3monocypher ,
.Xr crypto_ed25519_sign_init_second_pass 3monocypher ,
.Xr crypto_ed25519_sign_final 3monocypher ,
.Xr crypto_hmac_sha512 3monocypher ,
.Xr crypto_hmac_sha512_init 3monocypher ,
.Xr crypto_hmac_sha512_update 3monocypher ,
.Xr crypto_hmac_sha512_final 3monocypher
.Xr crypto_sha512 3monocypher ,
.Xr crypto_sha512_init 3monocypher ,
.Xr crypto_sha512_update 3monocypher ,
.Xr crypto_sha512_final 3monocypher
.Sh SECURITY CONSIDERATIONS
Using cryptography securely is difficult.
Flaws that never manifest under normal use might be exploited by a
clever adversary.
Cryptographic libraries are easy to misuse.
Even Monocypher allows a number of fatal mistakes.
.Pp
Users should follow a formal introduction to cryptography.
We currently recommend the
.Lk https://www.crypto101.io/ "Crypto 101 online course" .
.Ss Random number generation
Use the facilities of your operating system.
Avoid user space random number generators.
They are easy to misuse, which has lead to countless vulnerabilities
in the past.
For instance, the random stream may be repeated if one is not careful
with multi-threading, and forward secrecy is lost without proper key
erasure.
.Pp
Different system calls are available on different systems:
.Bl -bullet
.It
Recent versions of Linux (glibc >= 2.25, Linux >= 3.17), provide
.Fn getrandom
in
.In linux/random.h .
Do not set any flag.
.It
BSD, Darwin/macOS, illumos as well as Solaris provide
.Fn arc4random_buf
in
.In stdlib.h
or
.In bsd/stdlib.h .
This is easier to use than
.Fn getrandom .
.It
Windows provides
.Fn BCryptGenRandom .
.El
.Pp
The
.Pa /dev/urandom
special file may be used on systems that do not provide an easy to use
system call.
Be careful though, being a file makes
.Pa /dev/urandom
hard to use correctly and securely.
Reads may be interrupted, and more attacks are possible on a file than
on a system call.
.Ss Timing attacks
Monocypher runs in
.Dq constant time .
There is no flow from secrets to timings.
No secret dependent indices, no secret dependent branches.
Nevertheless, there are a couple important caveats.
.Pp
Comparing secrets should be done with constant-time comparison
functions, such as
.Xr crypto_verify16 3monocypher ,
.Xr crypto_verify32 3monocypher ,
or
.Xr crypto_verify64 3monocypher .
Do not use standard comparison functions.
They tend to stop as soon as a difference is spotted.
In many cases, this enables attackers to recover the secrets and
destroy all security.
.Pp
The Poly1305 authenticator, X25519, and EdDSA use multiplication.
Some older processors do not multiply in constant time.
If the target platform is something other than Intel or AMD x86_64,
double check how it handles multiplication.
In particular,
.Em ARM Cortex-M CPUs may lack constant-time multiplication .
Some VIA Nano x86 and x86_64 CPUs may lack constant-time multiplication
as well.
.Ss Data compression
Encryption does not hide the length of the input plaintext.
Most compression algorithms work by using fewer bytes to encode
previously seen data or common characters.
If an attacker can add data to the input before it is compressed and
encrypted, they can observe changes to the ciphertext length to recover
secrets from the input.
Researchers have demonstrated an attack on HTTPS to steal session
cookies when compression is enabled, dubbed
.Dq CRIME .
.Ss Forward secrecy
Long term secrets cannot be expected to stay safe indefinitely.
Users may reveal them by mistake, or the host computer might have a
vulnerability and be compromised.
To mitigate this problem, some protocols guarantee that past messages
are not compromised even if the long term keys are.
This is done by generating temporary keys, then encrypting messages
using them.
.Pp
In general, secrets that went through a computer should not be
compromised when this computer is stolen or infected at a later point.
.Pp
A first layer of defence is to explicitly wipe secrets as soon as
they are no longer used.
Monocypher already wipes its own temporary buffers, and contexts are
erased with the
.Fn crypto_*_final
functions.
The secret keys and messages however are the responsibility of the
user.
Use
.Xr crypto_wipe 3monocypher
to erase them.
.Pp
A second layer of defence is to ensure those secrets are not swapped
to disk while they are used.
There are several ways to do this.
The most secure is to disable swapping entirely.
Doing so is recommended on sensitive machines.
Another way is to encrypt the swap partition (this is less safe).
Finally, swap can be disabled locally \(en this is often the only
way.
.Pp
UNIX systems can disable swap for specific buffers with
.Fn mlock ,
and disable swap for the whole process with
.Fn mlockall .
Windows can disable swap for specific buffers with
.Fn VirtualLock .
.Pp
Core dumps cause similar problems.
Disable them.
Also beware of suspend to disk (deep sleep mode), which writes all RAM
to disk regardless of swap policy, as well as virtual machine snapshots.
Erasing secrets with
.Xr crypto_wipe 3monocypher
is often the only way to mitigate these dangers.
.Ss Undefined behaviour
Monocypher is a C library.
C is notoriously unsafe.
Using Monocypher incorrectly can trigger undefined behaviour.
This can lead to data corruption, data theft, or even arbitrary code
execution.
.Pp
Consider binding to a safe language if possible.
